Components of the Web
updated in 2017-05-01
no more updated
Course can be found here
https://classroom.udacity.com/courses/cs253/lessons/48737165/concepts/483298540923
wiki
https://developer.mozilla.org/en-US/docs/Learn
How the Web Works
https://www.udacity.com/wiki/cs253/unit-1
Introduction to the Web
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/AkjMCbSvTto.mp4
World Wide Web
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/NBI9kXzMHS0.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/uPTMmyZB7tw.mp4
File Types
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/ND8jAv7WrmU.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/VngVBqQYxVg.mp4
Components of the Web
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/kzyfIiVZPJA.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/cVU7hYn-B8I.mp4
Best Browser
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/57kH7Yole2k.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/eQDNuWOxaJ0.mp4
HTML Basics
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/5Kjx-NOwcSc.mp4
Intro to HTML Tags
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/VsxbuJWcxqA.mp4
Bold Tag
<b>content</b>
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/irJ9o1Uv6U8.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/JWld9DM-La4.mp4
Italics
<em>content</em>
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/4H23hC78J_A.mp4
Instructions: Make the phrase ‘HTML is reasonably straightforward’ italic.
Note: the textbox should have default text in it for you to edit. In the meantime, it should look like this:
HTML is <b>reasonably straightforward</b>
Your job is to make entire phase italicized by using the <em>
tag.
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/1079BoYQUD8.mp4
Missing End Tag
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/OWjh74s_uT4.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/pKouF71QK_c.mp4
Making Links
<tag attr="value">content</tag>
<a href="www.reddit.com">derp</a>
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/-0S9lBFHeo0.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/IjdvSD1tX8U.mp4
Errata:
URLs need the protocol
The URL in the link should be “http://udacity.com“ and not “udacity.com”.
If the default text is missing
The textbox should have default text in it for you to edit. In the meantime, it should look like this:
This website is my favorite
Your job is to make the words my favorite a link to udacity.com.
Adding Images
<img src="url" alt="text">
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/Le8i8TtDleU.mp4
Whitespace
<br>
<p>content</p>
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/dEtVii1eYYY.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/at-mlJ0KeMQ.mp4
Paragraph Tag
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/fSnKsMM6DRI.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/BH46s-hYLXg.mp4
Inline vs Block
inline: <b></b> <em></em> <img src="">
block: <p></p>
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/bOh9WjucNsA.mp4
Span and Div
inline:<span>text</span>
block: <div>text</div>
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/rv1Oy-EduCk.mp4
We now recommend using scratchpad.io instead of the HTML playground Steve refers to.
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/jCdjfORR7BI.mp4
Document Structure
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<b>context</b>
</body>
</html>
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/VL7Wm0UzY6s.mp4
Introducing URLs
Uniform Resource Locator
For those of you wondering what an IP address is, wikipedia has this to say:
An Internet Protocol address (IP address) is a numerical label assigned to each device (e.g., computer, printer) participating in a computer network that uses the Internet Protocol for communication. An IP address serves two principal functions: host or network interface identification and location addressing. Its role has been characterized as follows: "A name indicates what we seek. An address indicates where it is. A route indicates how to get there."
The URL is the human readable locator which resolves to a numerical IP Address and represents, as Steve says, "the location of the physical machine which has the document we want to fetch."
An example IPv4 address looks like this: 172.16.254.1
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/yKKGg6ihUCs.mp4
Correct URL
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/kUMasWPRKE4.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/4_nLjYoN8ks.mp4
Query Parameters
http://example.com/foo?p=1&q=neat
name=value
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/qv5XK91OhFo.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/e7N_4uaoNeI.mp4
Fragments
http://www.example.com/foo#fragment
http://example.com/foo?p=1#fragment
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/xq95EZdiOQc.mp4
Port
http://localhost:8000/
port-default=80
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/3P7e6R9LsRY.mp4
The url got slightly cut off at the end. It should read:
http://example.com:80/toys?p=foo#blah
Note that urls are, in general, case-sensitive, as are most subsections of urls. Keep that in mind when you answer! The full url is
http://example.com:80/toys?p=foo#blah
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/8hiQyL6lcBs.mp4
Get
http://www.example.com/foo
request line: GET /foo HTTP/1.1
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/8QjYUp3w5U0.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/rByBs2dt4dg.mp4
Most Common Method
GET
POST
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/F9Fp-LtY7So.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/pJNxDTa5uP0.mp4
Making Requests
request line: GET /foo?p=1 HTTP/1.1
Headers:
Name: value
Host: www.example.com
User-Agent: chrome v.17
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/5X7wcZuO5mU.mp4
User Agent Header
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/oJ6MBvzgPcQ.mp4
Valid Headers
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/RdZDK0121kI.mp4
Here is some information about headers that you might find useful.
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/li-vh81yxKI.mp4
HTTP Responses
request:
request-line:
GET /foo HTTP/1.1
response:
status-line:
HTTP/1.1 200 Ok
status code:
200 Ok
302 Found
404 Not found
500 Server Error
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/I4kUB17pTno.mp4
Response Headers
telnet www.udacity.com 80
GET / HTTP/1.0
Host: www.udacity.com
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/Ie0ONOZzNlw.mp4
NOTE:
This example does not work properly at the moment, as http://www.udacity.com redirects to https://www.udacity.com. The former uses the protocol HTTP while the site now actually uses the protocol HTTPS. The extra “S” in HTTPS stands for “secure”, and you will hear more about it later.
Opening A Terminal Window
Mac
Method 1:
Open Finder, then go to Applications -> Utilities -> Terminal
Method 2:
Open Spotlight, type ‘Terminal’, and the correct program should be the top result.
Linux
How you open the terminal varies depending on the specific distro and desktop environment. For Ubuntu, this page has a good introduction to the terminal and how to open it.
Windows
Open the Start Menu, then go to All Programs -> Accessories -> Command Prompt
Running Telnet
Running telnet in Windows requires enabling it in “Windows Features” first. This page.aspx) has a good introduction to enabling the telnet client in Windows up to version 8. Windows 10 is similar but you can find “Windows Features” with the search box in the taskbar.
Telnet should already be installed on Mac and Linux machines, so you should be able to copy the video exactly.
Telnet Request
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/CIDBvFiccXE.mp4
Since the video was recorded, the location header has changed to http://iana.org
You’ll need to use
telnet iana.org 80
and
GET /domains/example HTTP/1.0
Host: iana.org
instead of using domain example.com
Since the video was recorded, the location header has changed to http://example.iana.org GET /domains/example HTTP/1.0 Host: iana.org
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/Ly95z-I1qmA.mp4
Web Applications
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/_E8qXBHI4cg.mp4
Dynamic Content
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/543bDFHQKTs.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/4MlMQ5RJ4cc.mp4
Problem Set 1 - Creating Your First Cite
Google App Engine
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/Sj_OmHLEdEA.mp4
Check out the next lesson, “Problem Set 1 Help” for help getting Google App Engine running.
In the current version of Google App Engine (1.9.1 - 2014-03-19), the command line argument to choose a port in dev_appserver.py is no longer “-p”. The argument is now “–port”.
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/PNmji8qNL0s.mp4
tutorial in the forum
tutorial
https://console.cloud.google.com/home/dashboard?project=ssq-udacity-cs253
set path
http://docs.python-guide.org/en/latest/starting/install/win/
Welcome to Cloud Shell! Type "help" to get started.
ssq6554@ssq-udacity-cs253:~$ TUTORIALDIR=~/src/ssq-udacity-cs253/
type: TUTORIALDIR=~/src/ssq-udacity-cs253/
python_gae_quickstart-2017-05-03-15-34
ssq6554@ssq-udacity-cs253:~$ git clone https://github.com/GoogleCloudPlatform/appengine-try-python-flask.git $TUTORIALDIR
type: git clone https://github.com/GoogleCloudPlatform/appengine-try-python-flask.git $TUTORIALDIR
Cloning into '/home/ssq6554/src/ssq-udacity-cs253/python_gae_quickstart-2017-05-03-15-34'...
remote: Counting objects: 386, done.
remote: Total 386 (delta 0), reused 0 (delta 0), pack-reused 386
Receiving objects: 100% (386/386), 776.84 KiB | 355.00 KiB/s, done.
Resolving deltas: 100% (53/53), done.
ssq6554@ssq-udacity-cs253:~$ cd $TUTORIALDIR
type: cd $TUTORIALDIR
ssq6554@ssq-udacity-cs253:~/src/ssq-udacity-cs253/python_gae_quickstart-2017-05-03-15-34$ git checkout gcloud
type: git checkout gcloud
Branch gcloud set up to track remote branch gcloud from origin.
Switched to a new branch 'gcloud'
ssq6554@ssq-udacity-cs253:~/src/ssq-udacity-cs253/python_gae_quickstart-2017-05-03-15-34$ dev_appserver.py $PWD
type: dev_appserver.py $PWD
INFO 2017-05-03 07:45:50,733 devappserver2.py:692] Skipping SDK update check.
WARNING 2017-05-03 07:45:50,973 simple_search_stub.py:1152] Could not read search indexes from /tmp/appengine.None.ssq6554/search_indexes
INFO 2017-05-03 07:45:50,977 api_server.py:272] Starting API server at: http://0.0.0.0:48288
INFO 2017-05-03 07:45:50,980 dispatcher.py:205] Starting module "default" running at: http://0.0.0.0:8080
INFO 2017-05-03 07:45:50,981 admin_server.py:116] Starting admin server at: http://0.0.0.0:8000
INFO 2017-05-03 07:46:22,190 module.py:813] default: "GET /?authuser=0 HTTP/1.0" 200 12
^CINFO 2017-05-03 07:46:39,143 shutdown.py:45] Shutting down.
INFO 2017-05-03 07:46:39,144 api_server.py:863] Applying all pending transactions and saving the datastore
INFO 2017-05-03 07:46:39,144 api_server.py:866] Saving search indexes
ssq6554@ssq-udacity-cs253:~/src/ssq-udacity-cs253/python_gae_quickstart-2017-05-03-15-34$ gcloud app deploy app.yaml --project ssq-udacity-cs253
type: gcloud app deploy app.yaml --project ssq-udacity-cs253
You are about to deploy the following services:
- ssq-udacity-cs253/default/20170503t155355 (from [/home/ssq6554/src/ssq-udacity-cs253/python_gae_quickstart-2017-05-03-15-34/app.yaml])
Deploying to URL: [https://ssq-udacity-cs253.appspot.com]
Do you want to continue (Y/n)? y
type: y
Beginning deployment of service [default]...
Some files were skipped. Pass `--verbosity=info` to see which ones.
You may also view the gcloud log file, found at
remote: Counting objects: 386, done.
[/tmp/tmp.QsMJk5uBEu/logs/2017.05.03/15.53.52.611133.log].
╔════════════════════════════════════════════════════════════╗
╠═ Uploading 77 files to Google Cloud Storage ═╣
╚════════════════════════════════════════════════════════════╝
File upload done.
Updating service [default]...done.
Deployed service [default] to [https://ssq-udacity-cs253.appspot.com]
You can stream logs from the command line by running:
$ gcloud app logs tail -s default
To view your application in the web browser run:
$ gcloud app browse
ssq6554@ssq-udacity-cs253:~/src/ssq-udacity-cs253/python_gae_quickstart-2017-05-03-15-34$
succeed in deploying
http://ssq-udacity-cs253.appspot.com/
(success)Try locally
type:
gcloud init
gcloud components list
Your current Cloud SDK version is: 153.0.0
The latest available version is: 153.0.0
+-------------------------------------------------------------------------------
------------------------------+
| Components
|
+---------------+------------------------------------------------------+--------
------------------+-----------+
| Status | Name |
ID | Size |
+---------------+------------------------------------------------------+--------
------------------+-----------+
| Not Installed | App Engine Go Extensions | app-eng
ine-go | 48.4 MiB |
| Not Installed | Bigtable Command Line Tool | cbt
| 3.9 MiB |
| Not Installed | Cloud Datalab Command Line Tool | datalab
| < 1 MiB |
| Not Installed | Cloud Datastore Emulator | cloud-d
atastore-emulator | 15.4 MiB |
| Not Installed | Cloud Datastore Emulator (Legacy) | gcd-emu
lator | 38.1 MiB |
| Not Installed | Cloud Pub/Sub Emulator | pubsub-
emulator | 21.0 MiB |
| Not Installed | Emulator Reverse Proxy | emulato
r-reverse-proxy | 14.5 MiB |
| Not Installed | Google Container Registry's Docker credential helper | docker-
credential-gcr | 3.3 MiB |
| Not Installed | gcloud Alpha Commands | alpha
| < 1 MiB |
| Not Installed | gcloud Beta Commands | beta
| < 1 MiB |
| Not Installed | gcloud app Java Extensions | app-eng
ine-java | 128.6 MiB |
| Not Installed | gcloud app PHP Extensions (Windows) | app-eng
ine-php-windows | 19.1 MiB |
| Not Installed | gcloud app Python Extensions | app-eng
ine-python | 6.1 MiB |
| Not Installed | kubectl | kubectl
| 14.9 MiB |
| Installed | BigQuery Command Line Tool | bq
| < 1 MiB |
| Installed | Cloud SDK Core Libraries | core
| 5.9 MiB |
| Installed | Cloud Storage Command Line Tool | gsutil
| 2.9 MiB |
| Installed | Default set of gcloud commands | gcloud
| |
+---------------+------------------------------------------------------+--------
------------------+-----------+
To install or remove components at your current SDK version [153.0.0], run:
$ gcloud components install COMPONENT_ID
$ gcloud components remove COMPONENT_ID
To update your SDK installation to the latest version [153.0.0], run:
$ gcloud components update
type:gcloud components install app-engine-python
Restarting command:
$ gcloud components install app-engine-python
There appears a new cmd
window
Your current Cloud SDK version is: 153.0.0
Installing components from version: 153.0.0
+--------------------------------------------------+
| These components will be installed. |
+------------------------------+---------+---------+
| Name | Version | Size |
+------------------------------+---------+---------+
| gcloud app Python Extensions | 1.9.52 | 6.1 MiB |
+------------------------------+---------+---------+
For the latest full release notes, please visit:
https://cloud.google.com/sdk/release_notes
Do you want to continue (Y/n)?
type: y
#============================================================#
#= Creating update staging area =#
#============================================================#
#= Installing: gcloud app Python Extensions =#
#============================================================#
#= Creating backup and activating new installation =#
#============================================================#
Performing post processing steps...done.
Update done!
请按任意键继续. . .
open git bash
type: git clone https://github.com/GoogleCloudPlatform/python-docs-samples
type: cd G:/\Udacity/\cs253
Cloning into 'python-docs-samples'...
remote: Counting objects: 10835, done.
remote: Compressing objects: 100% (161/161), done.
remote: Total 10835 (delta 58), reused 1 (delta 1), pack-reused 10649
Receiving objects: 100% (10835/10835), 4.60 MiB | 190.00 KiB/s, done.
Resolving deltas: 100% (5742/5742), done.
type: cd python-docs-samples/\appengine/\standard/\hello_world
type: dev_appserver.py .
look in http://localhost:8080/
(failed)or
open cmd
Go to cloud.google.com
Login and create a project
Copy the project id and create a project in App Engine on your machine with same id
Install Google Cloud SDK
Open Google Cloud SDK shell
Type 'gcloud init '
It will show ur gmail id OR ask u to log in
Select the project you created in step 2
Type 'gcloud beta app create'
It will ask for region - choose the closest region
Hit Deploy button in App Engine OR Type 'gcloud app deploy ' in the shell
type: gcloud beta app create
You do not currently have this command group installed. Using it
requires the installation of components: [beta]
Restarting command:
$ gcloud components install beta
Installing component in a new window.
Please re-run this command when installation is complete.
$ C:\Users\SSQ\AppData\Local\Google\Cloud SDK\google-cloud-sdk\bin\..\lib\gc
loud.py beta app create
there opens a new window
Your current Cloud SDK version is: 153.0.0
Installing components from version: 153.0.0
+---------------------------------------------+
| These components will be installed. |
+----------------------+------------+---------+
| Name | Version | Size |
+----------------------+------------+---------+
| gcloud Beta Commands | 2017.03.24 | < 1 MiB |
+----------------------+------------+---------+
For the latest full release notes, please visit:
https://cloud.google.com/sdk/release_notes
Do you want to continue (Y/n)? y
#============================================================#
#= Creating update staging area =#
#============================================================#
#= Installing: gcloud Beta Commands =#
#============================================================#
#= Creating backup and activating new installation =#
#============================================================#
Performing post processing steps...done.
Update done!
请按任意键继续. . .
type: gcloud beta app create
ERROR: (gcloud.beta.app.create) The project [ssq-udacity-helloworld] already con
tains an App Engine application in region [us-central]. You can deploy your app
lication using `gcloud app deploy`.
type: cd G:\Udacity\cs253\helloworld
g:
type: gcloud app deploy
ERROR: gcloud crashed (UnicodeEncodeError): 'ascii' codec can't encode character
u'\xad' in position 22: ordinal not in range(128)
If you would like to report this issue, please run the following command:
gcloud feedback
To check gcloud for common problems, please run the following command:
gcloud info --run-diagnostics
failed
type:
C:\Users\SSQ>python "C:\Users\SSQ\AppData\Local\Google\Cloud SDK\google-cloud-sdk\bin\dev_appserver.py" G:\Udacity\cs253\python-docs-samples\appengine\standard\hello_world\app.yaml
success
(Fail)try locally again
open Google Cloud SDK Shell
type:
python "C:\Users\SSQ\AppData\Local\Google\Cloud SDK\google-cloud-sdk\bin\dev_appserver.py" G:\Udacity\cs253\helloworld\app.yaml
it appears:
Updates are available for some Cloud SDK components. To install them,
please run:
$ gcloud components update
Traceback (most recent call last):
File "C:\Users\SSQ\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform\go
ogle_appengine\dev_appserver.py", line 103, in <module>
_run_file(__file__, globals())
File "C:\Users\SSQ\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform\go
ogle_appengine\dev_appserver.py", line 97, in _run_file
execfile(_PATHS.script_file(script_name), globals_)
File "C:\Users\SSQ\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform\go
ogle_appengine\google\appengine\tools\devappserver2\devappserver2.py", line 899,
in <module>
main()
File "C:\Users\SSQ\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform\go
ogle_appengine\google\appengine\tools\devappserver2\devappserver2.py", line 895,
in main
dev_server.stop()
File "C:\Users\SSQ\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform\go
ogle_appengine\google\appengine\tools\devappserver2\devappserver2.py", line 775,
in stop
metrics.GetMetricsLogger().Stop()
File "C:\Users\SSQ\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform\go
ogle_appengine\google\appengine\tools\devappserver2\metrics.py", line 119, in St
op
total_run_time = int((Now() - self._start_time).total_seconds())
TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'NoneType'
type: gcloud components update
there’s a new window:
Your current Cloud SDK version is: 153.0.0
You will be upgraded to version: 154.0.1
+-------------------------------------------------+
| These components will be updated. |
+--------------------------+------------+---------+
| Name | Version | Size |
+--------------------------+------------+---------+
| Cloud SDK Core Libraries | 2017.05.04 | 6.0 MiB |
| gcloud cli dependencies | 2017.05.01 | 1.6 MiB |
+--------------------------+------------+---------+
The following release notes are new in this upgrade.
Please read carefully for information about new features, breaking changes,
and bugs fixed. The latest full release notes can be viewed at:
https://cloud.google.com/sdk/release_notes
154.0.1 (2017-05-04)
Cloud SDK
o Fixed issue in for gcloud init command. See
https://issuetracker.google.com/37968909.
154.0.0 (2017-05-03)
Cloud SDK
o Added support for project creation during the gcloud init flow.
Google Cloud Logging
o BUG FIX: gcloud beta logging sinks update would remove any start time
or end time from a sink
o gcloud beta logging sinks describe now reports values of start_time,
end_time and include_children
o The --include-children flag is now available for gcloud beta logging
sinks create to create sinks that apply to an organization or folder
and also to all of its child projects and folders.
Google Compute Engine
o Workaround problems with alpha and beta versions of compute ssh
command fail an attempt to use clouduseraccounts APIs.
Google Container Engine
o Promote --cluster-version from beta to GA in gcloud container
clusters create.
o '--no-source' flag for 'gcloud container builds submit' allows builds
with no source input.
Google Cloud ML Engine
o Added --config parameter to gcloud ml-engine versions create; this
parameter allows specifying scaling settings for a version.
Google Cloud Speech
o The gcloud ml speech commands to recognize spoken words in recorded
speech using the Cloud Speech API are now available in beta. Please run
gcloud beta ml speech --help or visit
https://cloud.google.com/speech/docs/ to learn more.
Google App Engine
o gcloud beta app deploy now attempts to use the Service Management API
to enable the Appengine Flexible Environment API for Flexible
deployments, if needed. Before deploying a Flexible app, please ensure
that the Flexible Environment API is enabled on the app's project.
o The new Node.js Runtime Builder pipeline will now be used to deploy
apps when using gcloud beta app deploy.
Google Cloud SQL
o Promote gcloud sql operations to GA. The beta surface still remains
and is identical.
Google Cloud Source Repositories
o Add a source repos describe command to describe a repository to the
beta track.
Do you want to continue (Y/n)?
type: y
#============================================================#
#= Creating update staging area =#
#============================================================#
#= Uninstalling: Cloud SDK Core Libraries =#
#============================================================#
#= Uninstalling: gcloud cli dependencies =#
#============================================================#
#= Installing: Cloud SDK Core Libraries =#
#============================================================#
#= Installing: gcloud cli dependencies =#
#============================================================#
#= Creating backup and activating new installation =#
#============================================================#
Performing post processing steps...done.
Update done!
To revert your SDK to the previously installed version, you may run:
$ gcloud components update --version 153.0.0
请按任意键继续. . .
type: ``
Traceback (most recent call last):
File "C:\Users\SSQ\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform\go
ogle_appengine\dev_appserver.py", line 103, in <module>
_run_file(__file__, globals())
File "C:\Users\SSQ\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform\go
ogle_appengine\dev_appserver.py", line 97, in _run_file
execfile(_PATHS.script_file(script_name), globals_)
File "C:\Users\SSQ\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform\go
ogle_appengine\google\appengine\tools\devappserver2\devappserver2.py", line 899,
in <module>
main()
File "C:\Users\SSQ\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform\go
ogle_appengine\google\appengine\tools\devappserver2\devappserver2.py", line 895,
in main
dev_server.stop()
File "C:\Users\SSQ\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform\go
ogle_appengine\google\appengine\tools\devappserver2\devappserver2.py", line 775,
in stop
metrics.GetMetricsLogger().Stop()
File "C:\Users\SSQ\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform\go
ogle_appengine\google\appengine\tools\devappserver2\metrics.py", line 119, in St
op
total_run_time = int((Now() - self._start_time).total_seconds())
TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'NoneType'
Deploy your app to the cloud
cd
to hello_world
dir and type gcloud app deploy
G:\Udacity\cs253\python-docs-samples\appengine\standard\hello_world>gcloud app deploy
You are about to deploy the following services:
- ssq-udacity-cs253/default/20170503t210424 (from [G:\Udacity\cs253\python-docs
-samples\appengine\standard\hello_world\app.yaml])
Deploying to URL: [https://ssq-udacity-cs253.appspot.com]
Do you want to continue (Y/n)? y
type y
Beginning deployment of service [default]...
Some files were skipped. Pass `--verbosity=info` to see which ones.
You may also view the gcloud log file, found at
[C:\Users\SSQ\AppData\Roaming\gcloud\logs\2017.05.03\21.04.21.920000.log].
#============================================================#
#= Uploading 0 files to Google Cloud Storage =#
#============================================================#
File upload done.
Updating service [default]...done.
Deployed service [default] to [https://ssq-udacity-cs253.appspot.com]
You can stream logs from the command line by running:
$ gcloud app logs tail -s default
To view your application in the web browser run:
$ gcloud app browse
type gcloud app browse
G:\Udacity\cs253\python-docs-samples\appengine\standard\hello_world>gcloud app browse
Opening [https://ssq-udacity-cs253.appspot.com] in a new tab in your default bro
wser.
Problem Set 1 Help
Intro
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/IFYmvf_RNT0.mp4
Install Google App Engine
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/euox_iFW2eM.mp4
Install Google App Engine
Make sure you are downloading Python 2 rather than Python 3, as this is what Google App Engine uses!
Changes to Google App Engine
The Google App Engine system (now part of Google Cloud) has changed a lot since this course was created. You will need to create an app with a new, unique name using the Developer Console before you can deploy it. For more information, take a look at these guides written by Udacity mentor Steven Wooding: (Windows), (Mac and Linux)
Installing Python on Linux
If you’re on a Mac or Linux machine, open a terminal and type ‘python -v’ at the prompt. If it returns some information about Python, then you already have Python installed! If not, then Mac users can follow the instructions in the video, and Linux users can use their package managers instead.
For Ubuntu or Debian, type ‘sudo apt-get install python’ into your terminal, then your password. For Fedora, type ‘sudo yum install python’ into your terminal, then your password. For other Linux distros, their should be documentation available for your specific package manager.
Running Google App Engine on Mac OS
Unfortunately Google no longer supports the GoogleAppengineLauncher program that Steve demonstrates in this video. You follow use the instructions below for Linux, or you can download the deprecated GoogleAppengineLauncher installer from the “Supporting Materials” list below. Warning: Use the GoogleAppengineLauncher program at your own peril! As Google no longer supports the tool it may stop working in the future. The gcloud command-line program is the currently supported tool.
Running Google App Engine on Linux
To run the Development Web Server locally, run:
dev_appserver.py myapp
Where myapp is the name you want your app to have.
To upload your code to Google App Engine, run:
appcfg.py update helloworld/
Where helloworld/ is the directory you’re running your web app from.
Further help is available here and here
Have questions? Head to the forums for discussion with the Udacity Community.
Supporting Materials
Windows Installation Guide for App Engine.pdf
GoogleAppEngineLauncher-1.9.40-OSX
https://discussions.udacity.com/t/problem-set-1-seems-to-be-nothing-like-help-video-shows/215184/3
Office Hours 1
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/QKTIOnISsCw.mp4
Forms and Input
https://www.udacity.com/wiki/cs253/unit-2
Introduction
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/3qgaev6_ZkY.mp4
Forms
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/OnptThLQb_k.mp4
User Input
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/qNdg3ZKoKnA.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/PmF0C6dWzFk.mp4
Naming Input
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/IOkzztrmxbg.mp4
how to implement play.html
:
https://discussions.udacity.com/t/unit2-this-is-fustrating/68505/2
Entering Input
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/JDwulMznybc.mp4
Try the HTML code
<form>
<input name="q">
</form>
Note that if you chose the text disappears in addition to the the URL changes with my text, that you are also correct. However, we’re focused on the latter, and arguably more interesting, of these two events. But, you may always re-submit your answer to any quiz.
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/vUHabH7bsTc.mp4
Submitting Input
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/easPpLBGf2w.mp4
<form>
<input name="q">
<input type="submit">
</form>
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/GMNVeltn0ms.mp4
The Action Attribute
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/UR-I9lkV3No.mp4
<form action="http://www.google.com/search">
<input name="q">
<input type="submit">
</form>
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/7YawG07y9lg.mp4
URL Encoding
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/Z3udiqgW1VA.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/lSjOr6_LaMs.mp4
Hello Webapp World
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/t9qqgCvHxgs.mp4
Content Type
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/a0k61hlrO9M.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/TGHZjKuxTB0.mp4
More Handlers
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/9624RoIt2pk.mp4
GET /testform?q=hello+world%21 HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8
Content-Type: ; charset="utf-8"
Cookie: _xsrf=2|69d62867|9814fd50905531e52e958841989ec6fb|1491708993; username-localhost-8890="2|1:0|10:1491841902|23:username-localhost-8890|44:NzI4YzlkMzc5MzIyNGQ5YTgxMWMzMDAyZDZiY2M4NTY=|69e8bf9e2ec4a47c684886256bda319f88bbbbe1cc4bf5c9193aa52c9449bab1"; username-localhost-8891="2|1:0|10:1491842087|23:username-localhost-8891|44:YThkM2ViMzc0NmJjNDVhNGE4YWI4OTgwZGE5M2RlYzk=|cd0850025b097f89ae64b4bda7911166954a2384ecd7eb8a17991270ad4111a4"; username-localhost-8889="2|1:0|10:1492581579|23:username-localhost-8889|44:NGM1MDZlMTUzNWE1NGUzNmFkYTNhMzRiMjdmOGYyNWY=|a15a04a3925f6c3954789ffbdb5b01f5bda3a0c4e9e47420ac1564c5302aaf9d"; username-localhost-8888="2|1:0|10:1493640422|23:username-localhost-8888|44:NjYzZDYzYThhNmQwNDZiODk2ZTVlZDU0YjkxOTI5MWM=|fb58980d83c777e3d64786ba156f12ab1834a9c404151d3d5dacb943ca4e0616"; Hm_lvt_3c8ad2ecdd2387b44044b1d7cd3536a9=1492997775,1493349600,1493631556,1493712288; _ga=GA1.1.1682530332.1487774100
Host: localhost:8080
Referer: http://localhost:8080/
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36
X-Appengine-Country: ZZ
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/6BpCLwYGwBA.mp4
The Method Attribute
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/eDotptZ1Nyo.mp4
405 Method Not Allowed
The method POST is not allowed for this resource.
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/BOnkFj9uMkg.mp4
http://localhost:8080/testform
hello world!
Methods and Parameters
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/E_OiAN5VKOM.mp4
import webapp2
form="""
<form method="post" action="/testform">
<input name="q">
<input type="submit">
</form>
"""
class MainPage(webapp2.RequestHandler):
def get(self):
#self.response.headers['Content-Type'] = 'text/plain'
self.response.write(form)
class TestHandler(webapp2.RequestHandler):
def post(self):
#q=self.request.get("q")
#self.response.out.write(q)
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write(self.request)
app = webapp2.WSGIApplication([
('/', MainPage),
('/testform',TestHandler)
], debug=True)
POST /testform HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8
Cache-Control: max-age=0
Content-Length: 16
Content-Type: application/x-www-form-urlencoded; charset="utf-8"
Content_Length: 16
Content_Type: application/x-www-form-urlencoded
Cookie: _xsrf=2|69d62867|9814fd50905531e52e958841989ec6fb|1491708993; username-localhost-8890="2|1:0|10:1491841902|23:username-localhost-8890|44:NzI4YzlkMzc5MzIyNGQ5YTgxMWMzMDAyZDZiY2M4NTY=|69e8bf9e2ec4a47c684886256bda319f88bbbbe1cc4bf5c9193aa52c9449bab1"; username-localhost-8891="2|1:0|10:1491842087|23:username-localhost-8891|44:YThkM2ViMzc0NmJjNDVhNGE4YWI4OTgwZGE5M2RlYzk=|cd0850025b097f89ae64b4bda7911166954a2384ecd7eb8a17991270ad4111a4"; username-localhost-8889="2|1:0|10:1492581579|23:username-localhost-8889|44:NGM1MDZlMTUzNWE1NGUzNmFkYTNhMzRiMjdmOGYyNWY=|a15a04a3925f6c3954789ffbdb5b01f5bda3a0c4e9e47420ac1564c5302aaf9d"; username-localhost-8888="2|1:0|10:1493640422|23:username-localhost-8888|44:NjYzZDYzYThhNmQwNDZiODk2ZTVlZDU0YjkxOTI5MWM=|fb58980d83c777e3d64786ba156f12ab1834a9c404151d3d5dacb943ca4e0616"; Hm_lvt_3c8ad2ecdd2387b44044b1d7cd3536a9=1492997775,1493349600,1493631556,1493712288; _ga=GA1.1.1682530332.1487774100
Host: localhost:8080
Origin: http://localhost:8080
Referer: http://localhost:8080/
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36
X-Appengine-Country: ZZ
q=hello+world%21
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/9Hj83VRhOQY.mp4
Differences Between Get and Post
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/UObINRj2EGY.mp4
Problems with Get
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/cIliEo0zOwg.mp4
When to Use Get and Post
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/CprytP12okM.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/KYPi9loZE-M.mp4
Passwords
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/xS71dGcER_s.mp4
<form>
<input type="password" name="q">
<input type="submit">
</form>
file:///G:/Udacity/cs253/L5%20Forms%20and%20Input/play.html?q=hello
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/oWvmNCuI47k.mp4
Checkboxes
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/bFK7ZIwnVik.mp4
<form>
<input type="checkbox" name="q">
<input type="submit">
</form>
file:///G:/Udacity/cs253/L5%20Forms%20and%20Input/play.html?
Multiple Checkboxes
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/Td_6JT-1MQ0.mp4
<form>
<input type="checkbox" name="q">
<input type="checkbox" name="r">
<input type="checkbox" name="s">
<br>
<input type="submit">
</form>
file:///G:/Udacity/cs253/L5%20Forms%20and%20Input/play.html?q=on&r=on
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/HEACkANsj9o.mp4
Radio Buttons
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/di_FzsEzyQk.mp4
<form>
<input type="radio" name="q">
<input type="radio" name="r">
<input type="radio" name="s">
<br>
<input type="submit">
</form>
file:///G:/Udacity/cs253/L5%20Forms%20and%20Input/play.html?q=on&r=on
Grouping Radio Buttons
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/QKxqWDx2bcs.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/5GqK_VmlrAY.mp4
Radio Button Values
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/xPTL73OT5IY.mp4
<form>
<input type="radio" name="q">
<input type="radio" name="q">
<input type="radio" name="q">
<br>
<input type="submit">
</form>
file:///G:/Udacity/cs253/L5%20Forms%20and%20Input/play.html?q=two
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/hTDenQDEvqU.mp4
Label Elements
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/XnBMnDGQqtw.mp4
<form>
<label>
One
<input type="radio" name="q" value="one">
</label>
<label>
Two
<input type="radio" name="q" value="two">
</label>
<label>
Three
<input type="radio" name="q" value="three">
</label>
<br>
<input type="submit">
</form>
Dropdowns
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/gVtTvYfc5NA.mp4
<form>
<select name="q">
<option>One</option>
<option>Two</option>
<option>Three</option>
</select>
<br>
<input type="submit">
</form>
file:///G:/Udacity/cs253/L5%20Forms%20and%20Input/play.html?q=Two
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/joUhCZw_zG0.mp4
Dropdowns and Values
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/q2jmRGrAixc.mp4
The Number One
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/mRTBZNTmimA.mp4
<form>
<select name="q">
<option value="1">the number One</option>
<option>Two</option>
<option>Three</option>
</select>
<br>
<input type="submit">
</form>
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/zCBUF8oDJPE.mp4
Validation
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/uC8ny0rTzIE.mp4
What Is Your Birthday?
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/Gx16pZ7crqU.mp4
import webapp2
form="""
<form method="post">
What's your birthday?
<br>
<label>
Month
<input type="text">
</label>
<label>
Day
<input type="text">
</label>
<label>
Year
<input type="text">
</label>
<br>
<br>
<input type="submit">
</form>
"""
class MainPage(webapp2.RequestHandler):
def get(self):
#self.response.headers['Content-Type'] = 'text/plain'
self.response.write(form)
app = webapp2.WSGIApplication([
('/', MainPage)
], debug=True)
405 Method Not Allowed
The method POST is not allowed for this resource.
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/psynonn163k.mp4
Handling Posts
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/NyIz4ht6NGI.mp4
import webapp2
form="""
<form method="post">
What's your birthday?
<br>
<label>
Month
<input type="text">
</label>
<label>
Day
<input type="text">
</label>
<label>
Year
<input type="text">
</label>
<br>
<br>
<input type="submit">
</form>
"""
class MainPage(webapp2.RequestHandler):
def get(self):
#self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write(form)
def post(self):
self.response.out.write("Thanks! That's a totally valid day!")
app = webapp2.WSGIApplication([
('/', MainPage)
], debug=True)
Handling Bad Data
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/fcrTA3_iHLY.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/u7vPsxvUNMA.mp4
Valid Month
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/mOAcUVFqIO0.mp4
Hint: You may want to look into the string.capitalize() function
In this answer video, Steve is using list comprehensions to create the dictionary of month abbreviations. If we were to translate this code: month_abbvs = dict((m[:3].lower(),m) for m in months)
it would be: month_abbvs = {} for m in months: month_abbvs[m[:3].lower()] = m You can read more about list comprehensions here
# -----------
# User Instructions
#
# Modify the valid_month() function to verify
# whether the data a user enters is a valid
# month. If the passed in parameter 'month'
# is not a valid month, return None.
# If 'month' is a valid month, then return
# the name of the month with the first letter
# capitalized.
#
months = ['January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December']
def valid_month(month):
# print valid_month("january")
# => "January"
# print valid_month("January")
# => "January"
# print valid_month("foo")
# => None
# print valid_month("")
# => None
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/a2sLiEgBl9k.mp4
month_abbvs = dict((m[:3].lower(),m) for m in months)
def valid_month(month):
if month:
short_month=month[:3].lower()
return month_abbvs.get(short_month)
Valid Day
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/jj44KNeNK3A.mp4
# -----------
# User Instructions
#
# Modify the valid_day() function to verify
# whether the string a user enters is a valid
# day. The valid_day() function takes as
# input a String, and returns either a valid
# Int or None. If the passed in String is
# not a valid day, return None.
# If it is a valid day, then return
# the day as an Int, not a String. Don't
# worry about months of different length.
# Assume a day is valid if it is a number
# between 1 and 31.
# Be careful, the input can be any string
# at all, you don't have any guarantees
# that the user will input a sensible
# day.
#
# Hint: The string function isdigit() might be helpful.
def valid_day(day):
# print valid_day('0')
# => None
# print valid_day('1')
# => 1
# print valid_day('15')
# => 15
# print valid_day('500')
# => None
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/6CdFM4grsXc.mp4
def valid_day(day):
if day and day.isdigit():
day=int(day)
if day>0 and day<=31:
return day
Valid Year
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/g1f2nOw7a9M.mp4
# -----------
# User Instructions
#
# Modify the valid_year() function to verify
# whether the string a user enters is a valid
# year. If the passed in parameter 'year'
# is not a valid year, return None.
# If 'year' is a valid year, then return
# the year as a number. Assume a year
# is valid if it is a number between 1900 and
# 2020.
#
def valid_year(year):
#print valid_year('0')
#=> None
#print valid_year('-11')
#=> None
#print valid_year('1950')
#=> 1950
#print valid_year('2000')
#=> 2000
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/YHEqWp6R0IA.mp4
def valid_year(year):
if year and year.isdigit():
year=int(year)
if year>1900 and year<=2020:
return year
Checking Validation
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/WbBDizcryiA.mp4
Responding Based On Verification
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/3EgN3NxgH-Y.mp4
import webapp2
form="""
<form method="post">
What's your birthday?
<br>
<label>
Month
<input type="text" name="month">
</label>
<label>
Day
<input type="text" name="day">
</label>
<label>
Year
<input type="text" name="year">
</label>
<br>
<br>
<input type="submit">
</form>
"""
def valid_day(day):
if day and day.isdigit():
day=int(day)
if day>0 and day<=31:
return day
months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
'September', 'October', 'November', 'December']
month_abbvs = dict((m[:3].lower(),m) for m in months)
def valid_month(month):
if month:
short_month=month[:3].lower()
return month_abbvs.get(short_month)
def valid_year(year):
if(year and year.isdigit()):
year = int(year)
if(year < 2020 and year > 1880):
return year
class MainPage(webapp2.RequestHandler):
def get(self):
#self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write(form)
def post(self):
user_month=valid_month(self.request.get('month'))
user_day=valid_day(self.request.get('day'))
user_year=valid_year(self.request.get('year'))
if not (user_month and user_day and user_year):
#self.response.out.write(user_month)
self.response.out.write(form)
else:
self.response.out.write("Thanks! That's a totally valid day!")
app = webapp2.WSGIApplication([
('/', MainPage)
], debug=True)
String Substitution
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/DYncK4Tuthc.mp4
# User Instructions
#
# Write a function 'sub1' that, given a
# string, embeds that string in
# the string:
# "I think X is a perfectly normal thing to do in public."
# where X is replaced by the given
# string.
# The function should return the new string.
given_string = "I think %s is a perfectly normal thing to do in public."
def sub1(s):
#print sub1("running")
# => "I think running is a perfectly normal thing to do in public."
#print sub1("sleeping")
# => "I think sleeping is a perfectly normal thing to do in public."
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/0h0RYI_MGtU.mp4
def sub1(s):
return given_string % s
Substituting Multiple Strings
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/ahNxN_Ly5sE.mp4
# User Instructions
#
# Write a function 'sub2' that, given two
# strings, embeds those strings in the string:
# "I think X and Y are perfectly normal things to do in public."
# where X and Y are replaced by the given
# strings.
# The function should return the new string.
given_string2 = "I think %s and %s are perfectly normal things to do in public."
def sub2(s1, s2):
# print sub2("running", "sleeping")
# => "I think running and sleeping are perfectly normal things to do in public."
# print sub2("sleeping", "running")
# => "I think sleeping and running are perfectly normal things to do in public."
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/K7mx3o3-X3Y.mp4
def sub2(s1, s2):
return given_string2 %(s1,s2)
Advanced String Substitution
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/4OXzeuhwM-E.mp4
# User Instructions
#
# Write a function 'sub_m' that takes a
# name and a nickname, and returns a
# string of the following format:
# "I'm NICKNAME. My real name is NAME, but my friends call me NICKNAME."
#
given_string2 = "I'm %(nickname)s. My real name is %(name)s, but my friends call me %(nickname)s."
def sub_m(name, nickname):
#print sub_m("Mike", "Goose")
# => "I'm Goose. My real name is Mike, but my friends call me Goose."
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/3iHZY-xJJUY.mp4
def sub_m(name, nickname):
return given_string2 % {"nickname":nickname,"name":name}
Substituting into Our Form
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/trxe2U-OplI.mp4
import webapp2
form="""
<form method="post">
What's your birthday?
<br>
<label>
Month
<input type="text" name="month">
</label>
<label>
Day
<input type="text" name="day">
</label>
<label>
Year
<input type="text" name="year">
</label>
<div style="color: red">%(error)s</div>
<br>
<br>
<input type="submit">
</form>
"""
def valid_day(day):
if day and day.isdigit():
day=int(day)
if day>0 and day<=31:
return day
months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
'September', 'October', 'November', 'December']
month_abbvs = dict((m[:3].lower(),m) for m in months)
def valid_month(month):
if month:
short_month=month[:3].lower()
return month_abbvs.get(short_month)
def valid_year(year):
if(year and year.isdigit()):
year = int(year)
if(year < 2020 and year > 1880):
return year
class MainPage(webapp2.RequestHandler):
def write_form(self, error=""):
self.response.out.write(form %{"error": error})
def get(self):
#self.response.headers['Content-Type'] = 'text/plain'
#self.response.out.write(form)
self.write_form()
def post(self):
user_month=valid_month(self.request.get('month'))
user_day=valid_day(self.request.get('day'))
user_year=valid_year(self.request.get('year'))
if not (user_month and user_day and user_year):
#self.response.out.write(user_month)
#self.response.out.write(form)
self.write_form("That doesn't look valid to me, friend.")
else:
self.response.out.write("Thanks! That's a totally valid day!")
app = webapp2.WSGIApplication([
('/', MainPage)
], debug=True)
Preserving User Input
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/BpNhr-xc0Nw.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/lwHWqkMijss.mp4
Problems with HTML Input
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/iWX-XylQsH8.mp4
import webapp2
form="""
<form method="post">
What's your birthday?
<br>
<label>
Month
<input type="text" name="month" value="%(month)s">
</label>
<label>
Day
<input type="text" name="day" value="%(day)s">
</label>
<label>
Year
<input type="text" name="year" value="%(year)s">
</label>
<div style="color: red">%(error)s</div>
<br>
<br>
<input type="submit">
</form>
"""
def valid_day(day):
if day and day.isdigit():
day=int(day)
if day>0 and day<=31:
return day
months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
'September', 'October', 'November', 'December']
month_abbvs = dict((m[:3].lower(),m) for m in months)
def valid_month(month):
if month:
short_month=month[:3].lower()
return month_abbvs.get(short_month)
def valid_year(year):
if(year and year.isdigit()):
year = int(year)
if(year < 2020 and year > 1880):
return year
class MainPage(webapp2.RequestHandler):
def write_form(self, error="", month="", day="", year=""):
self.response.out.write(form %{"error": error, "month": month, "day": day, "year": year})
def get(self):
#self.response.headers['Content-Type'] = 'text/plain'
#self.response.out.write(form)
self.write_form()
def post(self):
user_month = self.request.get('month')
user_day = self.request.get('day')
user_year = self.request.get('year')
month = valid_month(user_month)
day = valid_day(user_day)
year = valid_year(user_year)
if not (month and day and year):
#self.response.out.write(user_month)
#self.response.out.write(form)
self.write_form("That doesn't look valid to me, friend.", user_month, user_day, user_year)
else:
self.response.out.write("Thanks! That's a totally valid day!")
app = webapp2.WSGIApplication([
('/', MainPage)
], debug=True)
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/OpOOJcP-fY0.mp4
Handling HTML Input
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/K37Ldm4GSPo.mp4
HTML Escaping
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/teNvqTRP5EY.mp4
Using HTML Escaping
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/Hp-z-SVf3fw.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/2T-ubUA5xLk.mp4
Implementing HTML Escaping
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/NmCRWl-OZ60.mp4
# User Instructions
#
# Implement the function escape_html(s), which replaces
# all instances of:
# > with >
# < with <
# " with "
# & with &
# and returns the escaped string
# Note that your browser will probably automatically
# render your escaped text as the corresponding symbols,
# but the grading script will still correctly evaluate it.
#
def escape_html(s):
# print escape_html('>')
# print escape_html('<')
# print escape_html('"')
# print escape_html("&")
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/4NKBjlnV530.mp4
def escape_html(s):
for (i,o) in (("&","&"),(">","≷"),("<","<"),('"',""")):
s=s.replace(i,o)
return s
or
import cgi
def escape_html(s):
return cgi.escape(s, quote = True)
Problems Reinventing the Wheel
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/4YEcl5g3ADA.mp4
Current Limitations
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/_lRKZMPh5R8.mp4
import webapp2
import cgi
def escape_html(s):
return cgi.escape(s, quote = True)
form="""
<form method="post">
What's your birthday?
<br>
<label>
Month
<input type="text" name="month" value="%(month)s">
</label>
<label>
Day
<input type="text" name="day" value="%(day)s">
</label>
<label>
Year
<input type="text" name="year" value="%(year)s">
</label>
<div style="color: red">%(error)s</div>
<br>
<br>
<input type="submit">
</form>
"""
def valid_day(day):
if day and day.isdigit():
day=int(day)
if day>0 and day<=31:
return day
months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
'September', 'October', 'November', 'December']
month_abbvs = dict((m[:3].lower(),m) for m in months)
def valid_month(month):
if month:
short_month=month[:3].lower()
return month_abbvs.get(short_month)
def valid_year(year):
if(year and year.isdigit()):
year = int(year)
if(year < 2020 and year > 1880):
return year
class MainPage(webapp2.RequestHandler):
def write_form(self, error="", month="", day="", year=""):
self.response.out.write(form %{"error": error,
"month": escape_html(month),
"day": escape_html(day),
"year": escape_html(year)})
def get(self):
#self.response.headers['Content-Type'] = 'text/plain'
#self.response.out.write(form)
self.write_form()
def post(self):
user_month = self.request.get('month')
user_day = self.request.get('day')
user_year = self.request.get('year')
month = valid_month(user_month)
day = valid_day(user_day)
year = valid_year(user_year)
if not (month and day and year):
self.write_form("That doesn't look valid to me, friend.", user_month, user_day, user_year)
else:
self.response.out.write("Thanks! That's a totally valid day!")
app = webapp2.WSGIApplication([
('/', MainPage)
], debug=True)
Redirection
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/gjPdQ-ywbPM.mp4
Redirection Advantages
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/k84dleLQ-WI.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/eygchvjmP60.mp4
Implementing Redirection
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/46HPScqA0CA.mp4
import webapp2
import cgi
def escape_html(s):
return cgi.escape(s, quote = True)
form="""
<form method="post">
What's your birthday?
<br>
<label>
Month
<input type="text" name="month" value="%(month)s">
</label>
<label>
Day
<input type="text" name="day" value="%(day)s">
</label>
<label>
Year
<input type="text" name="year" value="%(year)s">
</label>
<div style="color: red">%(error)s</div>
<br>
<br>
<input type="submit">
</form>
"""
def valid_day(day):
if day and day.isdigit():
day=int(day)
if day>0 and day<=31:
return day
months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
'September', 'October', 'November', 'December']
month_abbvs = dict((m[:3].lower(),m) for m in months)
def valid_month(month):
if month:
short_month=month[:3].lower()
return month_abbvs.get(short_month)
def valid_year(year):
if(year and year.isdigit()):
year = int(year)
if(year < 2020 and year > 1880):
return year
class MainPage(webapp2.RequestHandler):
def write_form(self, error="", month="", day="", year=""):
self.response.out.write(form %{"error": error,
"month": escape_html(month),
"day": escape_html(day),
"year": escape_html(year)})
def get(self):
self.write_form()
def post(self):
user_month = self.request.get('month')
user_day = self.request.get('day')
user_year = self.request.get('year')
month = valid_month(user_month)
day = valid_day(user_day)
year = valid_year(user_year)
if not (month and day and year):
self.write_form("That doesn't look valid to me, friend.", user_month, user_day, user_year)
else:
self.redirect("/thanks")
class ThanksHandler(webapp2.RequestHandler):
def get(self):
self.response.out.write("Thanks! That's a totally valid day!")
app = webapp2.WSGIApplication([
('/', MainPage),
('/thanks', ThanksHandler)
], debug=True)
Problem Set 2
Rot13
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/uMGNwoFHfB4.mp4
In order to be graded correctly for this homework, there are a few things to keep in mind. We’ll be grading your web app by POSTing to your form and retrieving the text that has been encoded with ROT13. There are a few main issues you need to keep in mind in order for this to work:
- The textarea form element where the user inputs the text to encode must be named ‘text’. In other words, you must have ‘textarea name=”text”‘ for us to post to.
- The form method must be POST, not GET.
- You must enter the full url into the supplied textbox above, including the path. For example, our example app is running at http://udacity-cs253.appspot.com/unit2/rot13, but if we instead only entered http://udacity-cs253.appspot.com/ then the grading script would not work.
- Don’t forget to escape your output!
User Signup
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/SkSJp6IIZfw.mp4
In order to be graded correctly for this homework, there are a few things to keep in mind. We’ll be grading your web app by posting to your form and then checking the HTTP Response we receive. There are a few main issues you need to keep in mind in order for this to work:
- The form elements where the user inputs their username, password, password again, and email address must be named “username”, “password”, “verify”, and “email”, respectively.
- The form method must be POST, not GET.
- Upon invalid user input, your web app should re-render the form for the user.
- Upon valid user input, your web app should redirect to a welcome page for the user.
- This page must include both “Welcome” and the user’s username.
- You must enter the full url into the supplied textbox above, including the path. For example, our example app is running at http://udacity-cs253.appspot.com/unit2/signup, but if we instead only entered http://udacity-cs253.appspot.com/ then the grading script would not work.
Regular Expressions
A regular expression is a handy tool for matching text to a pattern. The regular expressions that we’re using to validate you input are as follows:
- Username: “^[a-zA-Z0-9_-]{3,20}$”
- Password: “^.{3,20}$”
- Email: “^[\S]+@[\S]+.[\S]+$”
Example code for validating a username is as follows:
import re
USER_RE = re.compile(r"^[a-zA-Z0-9_-]{3,20}$")
def valid_username(username):
return USER_RE.match(username)
More information on using regular expressions in Python can be found here
NOTE: When you go off to make real applications that require form validation, remember that using regex to check an email address is not quite as simple as we make it seem here. See this Stack Overflow question for more on email validation.
Rot13 Solution
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/NYzMnbSjOWA.mp4
The solution files are here. In order to open them, Windows users will need an archive utility that opens tgz files, like 7zip. Linux and Mac users can use the built-in functionality of their archive managers. Barring that, Linux and Mac users can directly use the command:
tar xf hw2.tgz
User Signup Solution
The solution files are here. In order to open them, Windows users will need an archive utility that opens tgz files, like 7zip. Linux and Mac users can use the built-in functionality of their archive managers. Barring that, Linux and Mac users can directly use the command:
tar xf hw2.tgz
Office Hours 2
Question 1
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/0uBFVZRVnrQ.mp4
Jinja2 Documentation
Question 2
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/5-UWdqZQOIw.mp4
Question 3
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/YY7joMbML8k.mp4
Question 4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/9vTJkEjXw6Q.mp4
We now have a course for beginner Object Oriented Programming in Python:
https://www.udacity.com/course/ud036
Question 5
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/rLPeR3A3CnM.mp4
Lesson 8: Lesson 2a-Templates
Writing a Basic Form
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/ScXJ5au8q_w.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/Bnh2EnFQdkw.mp4
Hidden Inputs
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/dfFiYpxh4js.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/EHACuozhDQA.mp4http://localhost:8080/?food=steak&food=eggs
Shopping List Take 1
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/h_EkzhX0D0I.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/87ieO3hrkDI.mp4
Introducing Templates
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/nT0wOJ3pQMw.mp4
jinja
Template Refactor
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/9HoEid5G4I4.mp4
Variable Substitution
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/D6q5TePkyo0.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/ppsNOLB7p4M.mp4
Errata
Don’t include quotation marks in your solution.
For additional clarification on the different render
methods, see this discussion thread.<h2>Hello, </h2>
Statement Syntax
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/13P8ncVwL_o.mp4
Testing Statement Syntax
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/zI4rmjjICmU.mp4
Templates and Types
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/4VYTtyHnKEs.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/d-PAPeH0bd0.mp4
|
|
Templates and Types
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/4VYTtyHnKEs.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/d-PAPeH0bd0.mp4
|
|
For Loop Syntax
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/KzZwbKZweKA.mp4
|
|
FizzBuzz
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/nxoQoSYJryc.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/KhrAMbp2MRA.mp4
|
|
Shopping List Take 2
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/BkqW2HKdL0M.mp4
get rid of
and
change following code in your shopping_list.html
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/9DaCBZImS54.mp4
self.request.get_all()self.request.get_all()
is a function that returns a list of all values that belong to string that matches a key in our query parameter. For example, if we pass in these query parameters: mysite.com?food=chips&food=fruit&food=milk,
then get_all()
will return a list that contains the strings chips,food,milk
Jinja2 Templates
Note that the bracket and the percent sign needs to be next to each other such as:
AND NOT
Escaping Templates
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/oQJCuxvH_VM.mp4
(recommand)first way
except:<li></li>
second way:<li></li>
Helpful Tips
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/4eXgr5beSkU.mp4
Template Inheritance
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/v81yoy1L1Bo.mp4
FizzBuzz Inheritance
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/ls9qRh8LVts.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/nmEgJJYhW-I.mp4
Conclusion
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/O60XPmSy1OY.mp4
Lesson 9: Lesson 3-Databases
note:
https://www.udacity.com/wiki/CS253%20Unit%203
Databases
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/EK0lMxBKRRw.mp4
Databases Continued
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/Y1av5nYgQKM.mp4
What Is a Database?
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/7yEjSZvZOAo.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/ngXxI8Q0WTg.mp4
Tables
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/7ldYR0Uis0I.mp4
Implementing Tables in Python
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/j-KIhN7LKJ8.mp4
Here is more information on namedtuple used in this exercise.
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/0jE0n6deDpk.mp4
Querying
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/2TFA879U_pc.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/aXwzyv11_4Q.mp4
Here is more information on sorting and Lambda expressions in Python .
Why Databases?
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/bGvBewhooJc.mp4
Types of Databases
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/MORw_tCy42A.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/Q3tsjEH9W-c.mp4
SQL
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/vgP5bfu0na4.mp4
Databases in Python
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/oleOUdXSfs0.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/F35zP0xOMFM.mp4
More Advanced SQL
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/aWIoeUm-HVA.mp4
Advanced SQL in Python
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/u2nQqxMfLE4.mp4
or
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/KsGqEVJsmO4.mp4
Order By
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/L55IfVfNvL8.mp4
You can find out more information about list comprehensions in the Python documentation and a supplementary lesson found here
better
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/kWvI1pvxYZ4.mp4
Joins
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/KddpLKB5JYA.mp4
Indexes
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/kgC5ZwM9BS8.mp4
Querying Links
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/dLAZvKNkZcs.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/ASrkP2-oBuM.mp4
Using Dictionaries As Indices
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/4c3leET2nzg.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/snkHGcSRRsk.mp4
Lookup
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/pq5cH9fx524.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/v-nktgcT2A4.mp4
output
Advantages of Indices
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/9CoBxepbSR4.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/da2uj4wK10Y.mp4
Real-World Example
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/31XAKJmp0sk.mp4
Indices for Sorting
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/REgL9DoFMdU.mp4
Another Real-World Example
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/XkuT8x6Y94A.mp4
Scaling Databases
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/dkhOZOmV7Fo.mp4
note:
method | replicate | shard
— | — | —
downside: | 1. doesn’t increase the write speed. 2. replication lag | 1. complex queries(range queries). 2. joins become difficult
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/NTpHCHAD2tM.mp4
Growing Databases
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/cFFM_GCvrYs.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/R9T3hQ1axaw.mp4
ACID
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/j-r6Fmzr4PM.mp4
note:
atumicity
consistency
isolation
durability
Google App Engine Datastore
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/r-wl-VZhNXo.mp4
GQL
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/SnaxUDryqaU.mp4
note:
GQL:
- all queries begin with SELECT *
- no joins
- all queries must be indexed
SQL:
run arbitrary queriesAutomatic Sharding and Replication
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/i4Fgm_XQ10M.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/TmPtKXgjZwQ.mp4ASCII Chan
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/dtlAAUtkvgQ.mp4Getting Started on ASCII Chan
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/hiyj6fDFm3c.mp4Creating the Form
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/yx4SvoTbiuI.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/gHsG6aYIaXo.mp4Textarea
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/u5iR0i5KOMY.mp4Form Handling
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/odSexP9bScI.mp4Form Handling Continued
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/iB5cwOZK0JU.mp4Creating Entities
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/dFX5Dp-v04s.mp4Datastore Types
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/_opjCcw2Al0.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/y4o26tQcAqc.mp4Creating Entities Continued
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/gmgKRL1wiCk.mp4Working with Entities
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/JUDj8fXp3eY.mp4Running Queries
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/h7LyH4cvYJo.mp4
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/cbpxkj6DGIg.mp4Styling
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/1pvAum4H7-Y.mp4Lesson 10: Problem Set 3-Building a Basic Blog
Basic Blog
https://s3.cn-north-1.amazonaws.com.cn/u-vid-hd/ysFzedoB3Rg.mp4